// Global Variables
let app = null;

// listen for messages from the user's current tab
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
    // TODO: Implement this
    // User is browsing the web app and may click a thread link to open it while the extension is open.
    if(request?.action === 'cunext_prime_thread'){
        const thread_id = request?.thread_id || null;
        const url = request?.url || null;
        const chat_id = request?.chat_id || null;
        app.primeThread(thread_id, url, chat_id);
        // Respond with success
        sendResponse({success: true});
    }
});

$('document').ready(function(){

    // Update #server_now_utc value
    try{
        const serverNowUTC = new Date().toISOString();
        $('#server_now_utc').val(serverNowUTC);
    }catch(e){
        console.error(e);
    }

    // load icons from bsi
    render_bsi();

    // Initialize app state
    app = new AppState();
    app.applyFontSizeSetting();
    
    // Update #notifications_opener with server url
    const serverURL = app.getSetting('server_url') || '';
    if(serverURL.length > 0){
        $('#notifications_opener').prop('href', `${serverURL}/notifications`).attr('target','_blank');
    }else{
        $('#notifications_opener').prop('href', '#').attr('target','_self');
    }

    // Get current user url and load threads, also, start notification polling
    setTimeout(() => {
        chrome.tabs.query({ active: true, currentWindow: true }, function(tabs) {
            const currentTab = tabs[0];
            if (currentTab) {
                try{
                    app.getThreads(currentTab.url);
                }catch(e){
                    console.error(e);
                }
            }
        });

        // Notification polling
        app.checkForNotifications();
        setInterval(() => {
            if(app) {
                app.checkForNotifications();
            }
        }, 30000); // Check for notifications every 30 seconds
    },200); // Wait for app to initialize

    // listeners
    // NOTE: use arrow functions to preserve "this" context inside app class
    $('#settings_opener').on('click', () => app.buildSettingsForm());
    $('#thread_locker').on('click', (e) => {
        e.preventDefault();
        if(app.toggleThreadLock()){ // locked if returns true
            $('#thread_locker').animate({opacity:'0'},300,function(){
                $('#thread_locker').addClass('locked').removeClass('unlocked').empty().append('<span class="bi bi-unlock"></span>&nbsp;Unlock');
                render_bsi();
                $('#thread_locker').animate({opacity:'1'},500);
            });
        }else{
            $('#thread_locker').animate({opacity:'0'},300,function(){
                $('#thread_locker').addClass('unlocked').removeClass('locked').empty().append('<span class="bi bi-lock"></span>&nbsp;Lock');
                render_bsi();
                $('#thread_locker').animate({opacity:'1'},500);
            });
        }
    });
    $('#get_threads_link').on('click',(e)=>{
        e.preventDefault();
        app.getThreads();
    });

    // Prevent default link_to_thread behavior
    $(document).on('click', '.link_to_thread', (e)=>{
        e.preventDefault();
        // Clone .thread parent
        const $this = $(e.currentTarget);
        const $thread = $this.closest('.thread');
        // Get all data attributes from $thread
        const dataAttrs = $thread.data();
        for(const key in dataAttrs){
            dashKey = key.replace(/([A-Z])/g, '-$1').toLowerCase();
            $('#thread-container').attr(`data-${dashKey}`, dataAttrs[key]);
        }
        setTimeout(()=>{
            render_threads(app.getSetting('server_url'),(e)=>{ // exit callback
                e.preventDefault();
                if(app.lockedThreadId){ // unlock
                    $('#thread_locker').trigger('click');
                }
                setTimeout(function(){
                    $('#get_threads_link').trigger('click');
                },100);
            });
        },30);
        const chatId = $this.attr('data-chat-id');
        const authorPK = $this.attr('data-author-public-key');
        app.loadThread(chatId, authorPK);
    });

    // Track when the user's current url changes and load threads for the new page (new tab, new page, etc.)
    var setWebNavListeners = setInterval(() => {
        // app is loaded when page ready.
        if(!app) return; 
        if(!chrome || !chrome.webNavigation) return;

        // Monitor when a user navigates to a new page in the current tab
        chrome.webNavigation.onCompleted.addListener((details) => { 
            // app is loaded when page ready.
            if(!app) return; 
            chrome.tabs.get(details.tabId, (tab) => {
                // return if tab not active
                if(!tab.active) return;
                try{
                    app.getThreads(tab.url);
                }catch(e){
                    console.error(e);
                }
            });
        });

        // Add a listener for sites that use pushState to change the URL without reloading the page.
        chrome.webNavigation.onHistoryStateUpdated.addListener((details) => {
            // app is loaded when page ready.
            if(!app) return; 
            chrome.tabs.get(details.tabId, (tab) => {
                // return if tab not active
                if(!tab.active) return; 
                try{
                    app.getThreads(tab.url);
                }catch(e){
                    console.error(e);
                }
            });
        });
        clearInterval(setWebNavListeners);
        setWebNavListeners = null;
    },100);

    // Listen for navigation on current tab
    chrome.tabs.onActivated.addListener((activeInfo) => { 
        // app is loaded when page ready.
        if(!app) return; 
        chrome.tabs.get(activeInfo.tabId, (tab) => {
            // return if tab not active
            if(!tab.active) return;
            try{
                app.getThreads(tab.url);
            }catch(e){
                console.error(e);
            }
        });
    });

    // Listen for new tab creation
    chrome.tabs.onCreated.addListener((tab) => { 
        // app is loaded when page ready.
        if(!app) return; 
        // return if tab not active
        if(!tab.active) return;
        try{
            app.getThreads(tab.url);
        }catch(e){
            console.error(e);
        }
    });
});
